<template>
  <t-drawer
    v-model:visible="formVisible"
    size="medium"
    size-draggable
    :footer="false"
    :header="isEdit ? '编辑' : '新增'"
  >
    <div>
      <t-form ref="formRef" :data="form" :rules="rules" @submit="onSubmit">
        <t-form-item name="parentId" label="上级菜单">
          <t-tree-select v-model="form.parentId" :data="treeData" placeholder="请选择上级菜单" />
        </t-form-item>
        <t-form-item name="type" label="菜单类型">
          <t-select v-model="form.type" :options="MENU_TYPES" placeholder="请选择菜单类型" />
        </t-form-item>
        <t-form-item name="title" label="菜单名称">
          <t-input v-model="form.title" placeholder="请填写菜单名称" />
        </t-form-item>
        <t-form-item name="permission" label="权限标识">
          <t-input v-model="form.permission" :options="ORG_TYPES" placeholder="请填写权限标识"></t-input>
        </t-form-item>
        <t-form-item name="sort" label="排序">
          <t-input v-model="form.sort" />
        </t-form-item>
        <t-form-item v-if="form.type === MenuType.MENU" name="keepAlive" label="是否缓存">
          <t-select v-model="form.keepAlive" placeholder="请选择" :options="NORMAL_STATUS" />
        </t-form-item>
        <t-form-item v-if="form.type === MenuType.MENU" label="图标">
          <!-- <t-space align="center">
            <t-button @click="iconVisible = true">选择图标</t-button>
            <component :is="iconOf(form.icon)" v-if="form.icon && iconOf(form.icon)" class="icon-show" :size="24" />
          </t-space> -->
          <t-select v-model="form.icon" placeholder="请选择图标">
            <t-option
              v-for="item in options"
              :key="item.stem"
              :value="item.stem"
              style="display: inline-block; font-size: 20px"
            >
              <div>
                <t-icon :name="item.stem" />
              </div>
            </t-option>
            <template #valueDisplay>
              <t-icon :name="form.icon" :style="{ marginRight: '8px' }" />
              {{ form.icon }}
            </template>
          </t-select>
        </t-form-item>
        <t-form-item v-if="form.type === MenuType.MENU" name="name" label="路由名称" :rules="menuRules('路由名称')">
          <t-input v-model="form.name" placeholder="请填写路由名称" />
        </t-form-item>
        <t-form-item v-if="form.type === MenuType.MENU" name="path" label="菜单编码" :rules="menuRules('菜单编码')">
          <t-input v-model="form.path" placeholder="请填写菜单编码" />
        </t-form-item>
        <t-form-item
          v-if="form.type === MenuType.MENU"
          name="component"
          label="菜单路径"
          :rules="menuRules('菜单路径')"
        >
          <t-input v-model="form.component" placeholder="请填写菜单路径" />
        </t-form-item>
        <t-form-item v-if="form.component === 'IFrame'" label="外部URL">
          <t-input v-model="form.frameSrc" placeholder="请填写" />
        </t-form-item>
        <t-form-item v-if="form.type === MenuType.MENU" name="hide" label="是否隐藏">
          <t-select v-model="form.hide" clearable :options="NORMAL_STATUS" placeholder="请选择" />
        </t-form-item>
        <t-form-item v-if="!isEdit" label="赋权角色" name="roleId" :rules="editRules('赋权角色')">
          <t-select
            v-model="form.roleId"
            placeholder="请选择赋权角色"
            clearable
            :options="roles"
            :keys="{
              value: 'id',
              label: 'roleName',
            }"
          />
        </t-form-item>
        <t-form-item>
          <t-button variant="outline" @click="close">取消</t-button>
          <t-button theme="primary" type="submit">确定</t-button>
        </t-form-item>
      </t-form>
    </div>
  </t-drawer>
  <!-- <icon-choose v-model:visible="iconVisible" @choose="(v:any) => (form.icon = v)" /> -->
</template>

<script lang="ts" setup>
import { isEmpty } from 'lodash';
import { manifest } from 'tdesign-icons-vue-next';
import { MessagePlugin, SubmitContext } from 'tdesign-vue-next';
import { computed, ref } from 'vue';
import { useRequest } from 'vue-request';

import { addMenu, getMenuList, updateMenu } from '@/api/upms/menu';
import { getRoleList } from '@/api/upms/role';
import { MENU_TYPES, MenuType, NORMAL_STATUS, ORG_TYPES } from '@/constants';
import { useVisible } from '@/hooks/visible';
import { assembleTree } from '@/utils/tools';

// 获取全部图标的列表
const options = ref(manifest);

const { data: roles } = useRequest(getRoleList);

const formRef = ref();

const initData = () => {
  return {
    id: '',
    name: '',
    title: '',
    permission: '',
    parentId: '0',
    icon: '',
    component: '',
    sort: '',
    path: '',
    frameSrc: '',
    keepAlive: '',
    roleId: '1',
    hide: '0',
  };
};

const rules = {
  title: [
    {
      required: true,
      message: '菜单名不能为空',
    },
  ],
  type: [
    {
      required: true,
      message: '菜单类型不能为空',
    },
  ],
  parentId: [
    {
      required: true,
      message: '上级菜单不能为空',
    },
  ],
  roleId: [
    {
      required: true,
      message: '赋权角色不能为空',
    },
  ],
};

const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  refreshList: {
    type: Boolean,
    default: false,
  },
  formData: {
    type: Object,
    default: () => {
      return {};
    },
  },
});

const emit = defineEmits<{
  (e: 'update:visible', v: boolean): void;
  (e: 'refresh'): void;
}>();

const form = ref(props.formData);

const { formVisible, close, open } = useVisible(props, emit);

// 判断是编辑还是新增
const isEdit = computed(() => !!form.value.id);

const { data: menuData } = useRequest(async () => assembleTree(await getMenuList()), {
  // 显示的时候刷新
  ready: computed(() => props.visible),
});

const treeData = computed(() => [{ label: '顶级菜单', value: '0', children: menuData.value }]);

const editRules = (label: string) => {
  return [
    {
      validator: (value: string) => !isEdit.value && !isEmpty(value),
      message: `${label}不能为空`,
    },
    {
      required: true,
    },
  ];
};

const menuRules = (label: string) => {
  return [
    {
      validator: (value: string) => form.value.type === MenuType.MENU && !isEmpty(value),
      message: `${label}不能为空`,
    },
    {
      required: true,
    },
  ];
};

const onSubmit = async (ctx: SubmitContext) => {
  if (ctx.validateResult === true) {
    if (isEdit.value) {
      await updateMenu(form.value).then(() => {
        MessagePlugin.success('修改成功');
      });
    } else {
      await addMenu(form.value).then(() => {
        MessagePlugin.success('添加成功');
      });
    }
    form.value = { ...initData };
    formVisible.value = false;
    emit('refresh');
  } else {
    MessagePlugin.warning(ctx.firstError);
  }
};

open(() => {
  const { id } = props.formData;
  if (id) {
    form.value = props.formData;
  } else {
    form.value = initData();
  }
});
</script>
<style scoped>
.overlay-options {
  display: inline-block;
  font-size: 40px;
}
</style>
